//--------------------------------------------------------------------
//     Author:Howe
//     Date: 2021-04-13 21:46:32 
//     Description:对此文件的更改可能会导致不正确的行为，并且如果重新生成代码，这些更改将会丢失。
//--------------------------------------------------------------------
using System;
using System.Threading.Tasks;
using Kylin.Wiki.Core;
using Kylin.Wiki.Model.Entity;
using Kylin.Wiki.IService;
using Kylin.Wiki.Core.Extensions.AutofacManager;
using Kylin.Wiki.Repository;
using Kylin.Wiki.Model.Api;
using System.Collections.Generic;
using Kylin.Wiki.Model.Dto;
using Kylin.Wiki.Core.Enum;
using System.Linq.Expressions;
using Kylin.Wiki.Model.View;
using System.Linq;
using Mapster;

namespace Kylin.Wiki.Services
{
    /// <summary>
    /// DeptServices
    /// </summary>	
    public class DeptService : Service<Dept>, IDeptService, IDependency
    { 
        private readonly IUserService _userService;

        public DeptService(IUnitOfWork unitOfWork, IRepository<Dept> repository
            , IUserService userService) : base(unitOfWork, repository)
        { 
            _userService = userService;
        }

        public ApiResult<bool> Create(Dept dept)
        {
            return new ApiResult<bool>(base.Add(dept, true) > 0, HttpStateCode.Success, "添加成功");
        }

        public ApiResult<bool> Delete(Dept dept)
        {
            if (_userService.Exists(x => x.DeptID == dept.DeptID))
                return new ApiResult<bool>(false, HttpStateCode.Error, "该部门正在使用中");
            if (base.Exists(x => x.PID == dept.DeptID))
                return new ApiResult<bool>(false, HttpStateCode.Error, "该部门正在使用中");
            return new ApiResult<bool>(base.Delete(dept, true) > 0, HttpStateCode.Success, "删除成功");
        }

        public ApiPageResult<List<DeptVM>> GetListByPage(DeptDTO deptDTO)
        {
            ApiPageResult<List<DeptVM>> result = new ApiPageResult<List<DeptVM>>();
            var orderBy = new Dictionary<string, QueryOrderBy>() { {
                    "OrderNum", QueryOrderBy.Asc
             } };
            var data = base.QueryablePage(deptDTO.PageIndex,
               deptDTO.PageSize,
               out int rowCount,
               x => x.Status == false,
               orderBy);
            var suser = data.Adapt<List<DeptVM>>();
            result.Data = ResolveDeptTree(suser);
            result.TotalCount = rowCount;
            result.PageIndex = deptDTO.PageIndex;
            result.PageSize = deptDTO.PageSize;
            result.TotalPages = (rowCount % deptDTO.PageSize) > 0 ? rowCount / deptDTO.PageSize + 1 : rowCount / deptDTO.PageSize;
            return result;
        }

        public ApiResult<bool> Update(Dept dept)
        {
            //判断是否存在部门
            if (!base.Exists(x => x.DeptID == dept.DeptID))
                return new ApiResult<bool>(false, HttpStateCode.Error, "该部门不存在");
            Expression<Func<Dept, object>>[] updatedProperties =
            {
                   p=>p.DeptName,
                   p=>p.PID,
                   p=>p.OrderNum,
                   p=>p.UpdateBy,
                   p=>p.UpdateOn
            };
            int result = base.Update(dept, updatedProperties, true);
            return new ApiResult<bool>(result > 0, HttpStateCode.Success, "修改成功");
        }

        /// <summary>
        /// 生成部门树
        /// </summary>
        /// <param name="menus"></param>
        /// <param name="parentId"></param>
        /// <returns></returns>
        private List<DeptVM> ResolveDeptTree(List<DeptVM> depts, int parentId = 0)
        {
            List<DeptVM> deptVMs = new List<DeptVM>();

            foreach (var dept in depts.Where(m => m.PID == parentId).OrderBy(m => m.OrderNum))
            {
                var children = ResolveDeptTree(depts, dept.DeptID);

                DeptVM deptVM = new DeptVM
                {
                    CreateBy = dept.CreateBy,
                    CreateOn = dept.CreateOn,
                    DeptID = dept.DeptID,
                    DeptName = dept.DeptName,
                    IsDelete = dept.IsDelete,
                    OrderNum = dept.OrderNum,
                    PID = dept.PID,
                    Status = dept.Status,
                    UpdateBy = dept.UpdateBy,
                    UpdateOn = dept.UpdateOn,
                    Children = children
                };

                deptVMs.Add(deptVM);

            }

            return deptVMs;
        }
    }

}
